package com.slipper.system.codeless.service;

import java.util.List;
import java.util.Map;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;

import com.google.gson.reflect.TypeToken;
import com.slipper.core.cache.CacheKey;
import com.slipper.core.cache.CacheUtil;
import com.slipper.util.Tool;
import com.slipper.util.UUID;
import org.springframework.stereotype.Service;
import jakarta.annotation.Resource;

import com.slipper.system.codeless.dao.PageCompParamDao;
import com.slipper.system.codeless.bo.PageCompParamBO;

import com.slipper.core.transaction.ReadTransactional;
import com.slipper.core.transaction.WriteTransactional;

@Service
@ReadTransactional
public class PageCompParamService {
    @Resource
    private PageCompParamDao pageCompParamDao;
    
    public PageCompParamBO queryBy(String id) {
        return pageCompParamDao.queryBy(id);
    }
    
    public List<PageCompParamBO> queryList(PageCompParamBO bo) {
        return pageCompParamDao.queryList(bo);
    }
    
    public PageInfo<PageCompParamBO> queryPage(PageCompParamBO bo) {
        PageHelper.startPage(bo.getPageNumber(), bo.getPageSize());
        return new PageInfo<>(pageCompParamDao.queryList(bo));
    }

    @WriteTransactional
    public int save(String compId, List<PageCompParamBO> list, String employeeId) {
        if (Tool.isBlank(compId)) {
            return 0;
        }

        for (int i=0; i<list.size(); i++) {
            PageCompParamBO param = list.get(i);
            param.setCompId(compId);
            param.setOrdinal(i);
            if (Tool.isBlank(param.getId())) {
                param.setId(UUID.getUUID());
                param.setUpdateId(employeeId);
                param.setCreateId(employeeId);
                param.setUpdateTime(System.currentTimeMillis());
                param.setCreateTime(System.currentTimeMillis());
                pageCompParamDao.insert(param);
            } else {
                param.setUpdateId(employeeId);
                param.setUpdateTime(System.currentTimeMillis());
                pageCompParamDao.update(param);
            }
        }

        // 删除被删除的数据
        PageCompParamBO qo = new PageCompParamBO();
        qo.setCompId(compId);
        pageCompParamDao.queryList(qo).stream()
                .filter(param -> list.stream().noneMatch(temp -> param.getId().equals(temp.getId())))
                .forEach(this::delete);
        CacheUtil.remove(CacheKey.PageCompParam.PREFIX + compId);
        return 1;
    }

    @WriteTransactional
    public void saveList(List<PageCompParamBO> list) {
        if (list == null) return;

        list.forEach(item -> {
            if (pageCompParamDao.queryBy(item.getId()) != null) {
                item.setUpdateTime(System.currentTimeMillis());
                pageCompParamDao.update(item);
            } else {
                item.setUpdateTime(System.currentTimeMillis());
                item.setCreateTime(System.currentTimeMillis());
                pageCompParamDao.insert(item);
            }
            CacheUtil.remove(CacheKey.PageCompParam.PREFIX + item.getCompId());
        });
    }

    public List<PageCompParamBO> queryByCompId(String compId) {
        List<PageCompParamBO> pageCompParamList = CacheUtil.get(
                CacheKey.PageCompParam.PREFIX + compId,
                new TypeToken<List<PageCompParamBO>>(){}.getType());
        if (pageCompParamList == null) {
            PageCompParamBO qo = new PageCompParamBO();
            qo.setCompId(compId);
            pageCompParamList = pageCompParamDao.queryList(qo);
            CacheUtil.set(CacheKey.PageCompParam.PREFIX + compId, pageCompParamList, 60 * 60);
        }
        return pageCompParamList;
    }

    @WriteTransactional
    public void deleteByCompId(String compId) {
        if (Tool.isBlank(compId)) {
            return;
        }

        PageCompParamBO qo = new PageCompParamBO();
        qo.setCompId(compId);
        pageCompParamDao.queryList(qo).forEach(this::delete);
        CacheUtil.remove(CacheKey.PageCompParam.PREFIX + compId);
    }

    @WriteTransactional
    public int delete(PageCompParamBO bo) {
        int result = pageCompParamDao.delete(bo.getId());
        CacheUtil.remove(CacheKey.PageCompParam.PREFIX + bo.getCompId());
        return result;
    }

    @WriteTransactional
    public void copyByCompId(String oldCompId, String newCompId, String employeeId, Map<String, String> paramMap) {
        queryByCompId(oldCompId).forEach(param -> {
            param.setId(UUID.getUUID());
            param.setPageParamId(paramMap.get(param.getPageParamId()));
            param.setCompId(newCompId);
            param.setUpdateId(employeeId);
            param.setCreateId(employeeId);
            param.setUpdateTime(System.currentTimeMillis());
            param.setCreateTime(System.currentTimeMillis());
            pageCompParamDao.insert(param);
        });
    }
}
